<template>
  <div ref="monitorBody">
    <Card :bordered="false" ref="monitorSearchBody">
      <Row>
        <Col span="18" style="text-align: left">
          <Select clearable v-model="selectLot.id" style="width:200px;text-align: left;" placeholder="停车场">
            <Option v-for="item in lotList" :value="item.id" :key="item.name">{{ item.name }}</Option>
          </Select>
          <Input v-model="txtSearch" placeholder="停车位编号/设备编号" style="width: 200px;margin-left:10px"/>
          <Select clearable v-model="selSpaceStatus.key" style="width:200px;text-align: left;margin-left:10px" placeholder="车位状态">
            <Option v-for="item in spaceStatus" :value="item.key" :key="item.value">{{ item.value }}</Option>
          </Select>
          <Button icon="ios-search" type="primary" @click="getParkingSpaceList(selectLot.id)" style="margin-left:10px"></Button>
        </Col>
      </Row>
    </Card>
    <Card :bordered="false">
      <Row>
        <Table @on-expand="expandRow" :height="tabHeight" :columns="columns" :data="parkingList" ref="tab"></Table>
      </Row>
    </Card>
    <div class="footStatusClz">
      <div class="footStatusTxtClz">连接状态:</div>
      <div style="float: left;margin-right: 1px;margin-top: 4px;">
        <div v-if="websocketStatus!=3" style="float: left;margin-left: 3px;" class="connectClz"></div>
        <span v-if="websocketStatus!=3" class="footStatusTxtClz" style="margin-left: 2px;margin-top: -3px;">连接</span>
        <div v-if="websocketStatus==3" style="float: left;margin-left: 3px;" class="disconnectClz"></div>
        <span v-if="websocketStatus==3" class="footStatusTxtClz" style="margin-left: 2px;margin-top: -3px;">断开</span>
      </div>
    </div>
    <Modal
      v-model="modal.status"
      title="查看历史"
      :top="0"
      width="80%"
      height="100%">
      <!--<history-state-monitor-data v-if="modal.status" :deviceCode="modal.deviceCode" :row="data"></history-state-monitor-data>-->
      <Tabs type="card" value="state">
        <TabPane label="状态" name="state">
          <history-state-monitor-data v-if="modal.status" :deviceCode="modal.deviceCode" :row="data"></history-state-monitor-data>
        </TabPane>
        <TabPane label="心跳" name="upload">
          <history-monitor-data v-if="modal.status" :deviceCode="modal.deviceCode" :row="data"></history-monitor-data>
        </TabPane>
        <TabPane label="其他" name="other">
          <history-other-monitor-data v-if="modal.status" :deviceCode="modal.deviceCode" :row="data"></history-other-monitor-data>
        </TabPane>
      </Tabs>
      <div slot="footer" style="display:none">
      </div>
    </Modal>

  </div>
</template>

<script>
  import urlSource from '../../api/urlSource'
  import monitorExpandRow from './components/monitorDataExpandRow'
  import historyMonitorData from './components/historyMonitorData'
  import historyOtherMonitorData from './components/historyOtherMonitorData'
  import historyStateMonitorData from './components/historyStateMonitorData'

  export default {
    name: "space",
    components: {monitorExpandRow,historyMonitorData,historyOtherMonitorData,historyStateMonitorData},
    data() {
      return {
        modal : {
          status: false,
          deviceCode: '',
        },
        expandChildHeight: '',
        lotList: [],//停车场列表
        selectLot: {
          id: "",
          name: ""
        },
        selSpaceStatus:{
          key: '',
          value:''
        },
        spaceStatus: [
          {
            key: 0,
            value: "空闲",
          },
          {
            key: 1,
            value: "占有",
          },
          {
            key: 2,
            value: "初始化",
          },
          {
            key: 4,
            value: "离线",
          }
        ],
        txtSearch: "",
        columns: [
          {
            type: 'expand',
            width: 60,
            align: 'center',
            render: (h, params) => {
              this.parkingList.forEach(v => {
                if (v.id == params.row.id) {
                  params.row.devData = v.devData;
                }
              })
              return h(monitorExpandRow, {
                props: {
                  row: params.row,
                  // expandChildHeight: this.expandChildHeight,
                  // parentTabHeight: this.tabHeight
                },
              })
            }
          },
          {
            type: 'index',
            width: 60,
            align: 'center'
          },
          {
            title: '车位编号',
            key: 'code'
          },
          {
            title: '设备编号',
            key: 'deviceCode'
          },
          {
            title: '所属停车场',
            key: 'lotId',
            render: (h, params) => {
              var parkingLotName = "";
              this.lotList.forEach(v => {
                if (v.id == params.row.lotId) {
                  parkingLotName = v.name;
                }
              })
              return h('div', [
                h('div', parkingLotName)
              ]);
            }
          },
          {
            title: '当前状态',
            key: 'status',
            render: (h, params) => {
              var statusName = "";
              this.spaceStatus.forEach(v => {
                if (v.key == params.row.status) {
                  statusName = v.value;
                }
              })
              return h('div', [
                h('div',{
                  class: (params.row.status==0)? "tagBtn tag-success" : (params.row.status==1)? "tagBtn tag-danger" : (params.row.status==4) ? "tagBtn tag-info" :"tagBtn"

                }, statusName)
              ]);
            }
          },
          {
            title: '更新时间',
            key: 'updateTime',
            width: 180
          },
          {
            title: '历史数据',
            width: 150,
            key: 'historyData',
            render: (h, params) => {
              return h('div', [
                h('Button', {
                  props: {
                    type: 'primary',
                    size: 'small'
                  },
                  style: {
                    marginRight: '5px'
                  },
                  on: {
                    click: () => {
                      this.modal.status = true;
                      this.modal.deviceCode = params.row.deviceCode;
                    }
                  }
                }, '查看'),
              ]);
            }
          },
        ],
        parkingList: [],
        text: '',
        data: '',
        websocket: null,
        expandRowMap: '',
        tabHeight: '',
        tabHeightTemp: '',
        websocketStatus: ''
      }
    },
    methods: {
      //获取停车场列表
      getParkingLot() {
        let url = urlSource.apiUrl + "parkingLots/" + this.$store.state.user.orgId + "/all"
        this.$http.get(url).then(res => {
          this.lotList = res.data
          this.selectLot.id = this.lotList[0].id;
          this.getParkingSpaceList(this.selectLot.id);
        }).catch(err => {

        })
      },
      //获取停车位列表
      getParkingSpaceList(lotId) {
        if(!lotId){
          this.$Message.warning('请先选择停车场');
          return ;
        }
        let url = urlSource.apiUrl + "monitorDevice/lots/" + lotId;
        if(this.txtSearch){
          url += '?devCode=' + this.txtSearch;
        }
        if(this.selSpaceStatus.key=='0' || this.selSpaceStatus.key=='1'){
          if(this.txtSearch){
            url += '&parkingState=' + this.selSpaceStatus.key;
          }else{
            url += '?parkingState=' + this.selSpaceStatus.key;
          }
        }
        this.$http.get(url).then(res => {
          if (res.data != "" && res.data != null) {
            if(this.parkingList.length>0){
              this.parkingList = [];
            }
            console.log(res.data)
            res.data.forEach((d)=>{
              let otherDataObj = d.otherDataJson=='' ? null : d.otherDataJson;
              if(d.dataJson){
                d.parkSpace.devData = JSON.parse(d.dataJson);
                d.parkSpace.devData.hardData = JSON.parse(otherDataObj);
                // 如果当前时间与设备更新时间相差大于3个 HeartBeat ,则说命该设备处于离线状态
                let betweenTime =  new Date().getTime() - this.dateStr2dateMills(d.eventTime);
                if(d.data.heartBeat){//heartBeat 为1，代表十秒
                  if(betweenTime > d.data.heartBeat*10*1000){
                    d.parkSpace.status = '4';
                  }else{
                    d.parkSpace.status = d.data.code=='3' ? '2' : d.data.parkingState;
                  }
                }else{
                  //如果 heartBeat 没有值，默认5min 分钟就处于休眠状态
                  if(betweenTime > 5*60*1000){
                    d.parkSpace.status = '4';
                  }else{
                    d.parkSpace.status = d.data.code=='3' ? '2' : d.data.parkingState;
                  }
                }
                d.parkSpace.statusTime = d.statusTime;
                d.parkSpace.deviceId = d.deviceId;
                if(d.data.code=='3'){
                  this.initMonitorDataExpand(d.parkSpace);
                }
              }else{
                d.parkSpace.devData = {};
                d.parkSpace.status = '2';
                this.initMonitorDataExpand(d.parkSpace);
              }
              this.initExpandData(d.parkSpace)
              this.parkingList.push(d.parkSpace);
            });
            //过滤设备初始化数据
            if(this.selSpaceStatus.key==2 || this.selSpaceStatus.key==4){
              let tmpList = [];
              this.parkingList.forEach(v=>{
                if(v.status==this.selSpaceStatus.key){
                  tmpList.push(v);
                }
              });
              this.parkingList = tmpList;
            }
            //查询空闲的数据中过滤离线数据
            if(this.selSpaceStatus.key=='0' || this.selSpaceStatus.key=='1'){
              let tmpList = [];
              this.parkingList.forEach(v=>{
                if(v.status!=4){
                  tmpList.push(v);
                }
              });
              this.parkingList = tmpList;
            }
          } else {
            this.parkingList = []
          }
          this.expandRowMap.clear()
        }).catch(err => {

        })
      },
      //时间字符串转毫秒值
      dateStr2dateMills(time){
        time = time.replace(new RegExp("-","gm"),"/");
        return (new Date(time)).getTime();
      },
      initMonitorDataExpand(data){
        //当电信平台未推送数据时，初始化相关变量
        data.devData.RunTime = '初始化';
        data.devData.Signal = '初始化';
        data.devData.RemainingBattery = '初始化';
      },
      //展开行事件
      expandRow(row, status) {
        this.expandRowMap.set(row.deviceCode,status);
        //动态计算表格高度
        if(status){
          //计算表格中数据的高度
          let dataHeight = this.parkingList.length * 50 + 420;
          this.tabHeight += 377;
        }else{
          if(this.tabHeightTemp<this.tabHeight){
            this.tabHeight -= 377;
          }
        }
      },
      initWebSocket() {
        if ('WebSocket' in window) {
          this.websocket = new WebSocket(urlSource.socketUrl)
        } else {
          alert('当前浏览器 Not support websocket')
        }
        //连接错误
        this.websocket.onerror = this.setErrorMessage
        //连接成功
        this.websocket.onopen = this.setOnopenMessage
        //收到消息的回调
        this.websocket.onmessage = this.setOnmessageMessage
        //连接关闭的回调
        this.websocket.onclose = this.setOncloseMessage
        //监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。
        window.onbeforeunload = this.onbeforeunload
      },
      setErrorMessage() {
        this.data = "WebSocket连接发生错误" + '   状态码：' + this.websocket.readyState;
      },
      setOnopenMessage() {
        this.websocketStatus = this.websocket.readyState;
        this.data = "WebSocket连接成功" + '   状态码：' + this.websocket.readyState;
        console.log(this.data)
      },
      setOnmessageMessage(event) {
        // this.data = '服务端返回：' + event.data;
        this.data = event.data;
        this.getServerDeviceData(this.data);

      },
      setOncloseMessage() {
        this.data = "WebSocket连接关闭" + '   状态码：' + this.websocket.readyState;
        this.websocketStatus = this.websocket.readyState;
        console.log(this.data)
      },
      onbeforeunload() {
        this.closeWebSocket();
      },
      //websocket发送消息
      send() {
        this.websocket.send(this.text)
        this.text = ''
      },
      closeWebSocket() {
        this.websocket.close()
      },
      getServerDeviceData(deviceData){
        console.log(deviceData)
        if(deviceData && this.parkingList){

          this.parkingList.forEach((data)=>{
            let obj = JSON.parse(deviceData);
            let devDataObj = obj.data;
            if(devDataObj && data.deviceCode == devDataObj.DeviceID){
              let temp = data.devData.hardData;
              data.status = devDataObj.Code=='3' ? '2' : devDataObj.ParkingState;
              data.updateTime = obj.eventTime;
              if(devDataObj.Code=='1' || devDataObj.Code=='3'){
                devDataObj.RunTime = data.devData.RunTime;
                devDataObj.Signal = data.devData.Signal;
                devDataObj.RemainingBattery = data.devData.RemainingBattery;
                //如果磁感强度也要不变化，在此处加就可以了
              }
              data.devData = devDataObj;
              data.devData.hardData = temp;
              data.devData.serviceId = obj.serviceId;
              data.statusTime = !obj.statusTime ? '' : obj.statusTime;
            }else{
              //TODO 如果当前时间与设备更新时间相差大于3个 HeartBeat ,则说命该设备处于离线状态
              let betweenTime =  new Date().getTime() - this.dateStr2dateMills(data.updateTime);
              console.log(obj.deivceCode,betweenTime)
              if(devDataObj.HeartBeat){//heartBeat 为1，代表十秒
                if(betweenTime > devDataObj.HeartBeat*10*1000){
                  data.status = '4';
                }else{
                  data.status = devDataObj.Code=='3' ? '2' : devDataObj.ParkingState;
                }
              }else{
                //如果 heartBeat 没有值，默认5min 分钟就处于休眠状态
                if(data.status!='2'){
                  if(betweenTime > 5*60*1000){
                    data.status = '4';
                  }else{
                    data.status = devDataObj.Code=='3' ? '2' : devDataObj.ParkingState;
                  }
                }
              }
            }
            this.initExpandData(data);
            data._expanded = this.expandRowMap.get(data.deviceCode);
          });
        }
      },

      sendMessage2Server(){
        let msg = "客户端发送消息";
        let url = urlSource.apiUrl + "deviceData/webSocketTest/"+msg;
        this.$http.get(url).then(res => {
        }).catch(err => {

        })
      },
      initExpandData(rowData){
        let devData = rowData.devData;
        if(!devData.hardData){
          devData.hardData = {};
          devData.hardData.Sensitivity = '初始化';
          devData.hardData.FirmwareVersion = '初始化';
          devData.hardData.HardwareVersion = '初始化';
          devData.hardData.ProtocolVersion = '初始化';
          devData.hardData.IMEI = '初始化';
          devData.hardData.IMEIFactory = '初始化';
          devData.hardData.IotNum = '初始化';
          devData.hardData.TelecomOperators = '初始化';
          devData.hardData.DeviceBrand = '初始化';
          devData.hardData.ProduceDate = '初始化';
        }
      }

    },
    mounted() {
      this.$nextTick(() => {
        this.expandRowMap = new Map();
        this.getParkingLot();
        this.initWebSocket();
        this.tabHeightTemp = this.tabHeight = window.innerHeight-186;
      })
    },
    beforeDestroy() {
      this.expandRowMap.clear()
      this.onbeforeunload();
      this.tabHeight = 0;
    }
  }
</script>

<style lang="less">
  .vertical-center-modal {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .ivu-modal {
    top: 2px;
  }
  .tagBtn {
    background-color: rgba(64, 158, 255, 0.15);
    display: inline-block;
    height: 32px;
    width: 60px;
    text-align: center;
    line-height: 30px;
    font-size: 12px;
    color: #409eff;
    border-radius: 4px;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    border: 1px solid rgba(64, 158, 255, 0.2);
    white-space: nowrap;
    font-weight: bold;
  }
  .tag-success{
    background-color: rgba(103,194,58,.15);
    border-color: rgba(103,194,58,.2);
    color: #67c23a;
  }
  .tag-danger {
    background-color: hsla(0,87%,69%,.15);
    border-color: hsla(0,87%,69%,.2);
    color: #f56c6c;
  }
  .tag-info {
    background-color: gainsboro;
    border-color: ghostwhite;
    color: grey;
  }
  /*.tagBtn /deep/ .tagBtn1 {*/
    /*background-color: rgba(64, 158, 255, 0.15);*/
    /*display: inline-block;*/
    /*height: 32px;*/
    /*width: 60px;*/
    /*text-align: center;*/
    /*line-height: 30px;*/
    /*font-size: 12px;*/
    /*color: #409eff;*/
    /*border-radius: 4px;*/
    /*-webkit-box-sizing: border-box;*/
    /*box-sizing: border-box;*/
    /*border: 1px solid rgba(64, 158, 255, 0.2);*/
    /*white-space: nowrap;*/
    /*font-weight: bold;*/
  /*}*/
  /*.tag-success1{*/
    /*background-color: rgba(103,194,58,.15);*/
    /*border-color: rgba(103,194,58,.2);*/
    /*color: #67c23a;*/
  /*}*/
  /*.tag-danger1 {*/
    /*background-color: hsla(0,87%,69%,.15);*/
    /*border-color: hsla(0,87%,69%,.2);*/
    /*color: #f56c6c;*/
  /*}*/
  .footStatusClz {
    position: fixed;
    bottom: 0px;
    left: 211px;
    background: #ddd;
    width:100%;
    height: 21px;
    padding-left: 20px;
    z-index: 999;
  }
  .connectClz {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1px solid #22de22;
    background: #22de22;
  }
  .disconnectClz {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1px solid red;
    background: red;
  }
  .footStatusTxtClz {
    color: #333;
    float: left;
    margin-right: 6px;
  }
</style>
